<html>
<head><meta charset="utf-8"><title>Implementing Try for unit · t-libs · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/index.html">t-libs</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Implementing.20Try.20for.20unit.html">Implementing Try for unit</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="220111236"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Implementing%20Try%20for%20unit/near/220111236" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Joshua Barretto <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Implementing.20Try.20for.20unit.html#220111236">(Dec 16 2020 at 12:52)</a>:</h4>
<p>Is there any reason this isn't done? Many times I've want to just exit out of a function if an <code>Option</code> is a <code>None</code>. This feels like an intuitive thing to do given that the alternative is to construct a syntactically complex <code>if</code>/<code>let</code>/<code>else</code>/<code>return</code> that breaks up method chaining.</p>



<a name="220136321"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Implementing%20Try%20for%20unit/near/220136321" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> cuviper <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Implementing.20Try.20for.20unit.html#220136321">(Dec 16 2020 at 16:16)</a>:</h4>
<p>So you don't want to use <code>?</code> on a unit value, just want to have a unit return be able to convert from an early <code>None</code>.</p>



<a name="220136544"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Implementing%20Try%20for%20unit/near/220136544" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> cuviper <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Implementing.20Try.20for.20unit.html#220136544">(Dec 16 2020 at 16:18)</a>:</h4>
<p>I think that halfway use is why it's not done. There was a redesign of <code>Try</code> that separated those concepts -- I think it was <span class="user-mention" data-user-id="125270">@scottmcm</span>'s <code>Bubble</code></p>



<a name="220145257"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Implementing%20Try%20for%20unit/near/220145257" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> scottmcm <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Implementing.20Try.20for.20unit.html#220145257">(Dec 16 2020 at 17:24)</a>:</h4>
<p>cuviper is correct; today that cannot be done without also allowing <code>()??????????</code> to be legal, which is undesirable.</p>
<p>I don't know that there's appetite for the asymmetrical case in general, or for <code>None?</code> to work in <code>()</code> specifically.  I think it's likely that at least the answer would be to wait for <code>try{}</code> before adding it -- one could plausibly do something like <code>let _: Option&lt;()&gt; = try { ... function body here ... };</code> to handle the specific case, which would have the nice consequence of emphasizing to the reader how the control flow will work in the block.  (And since it's for the whole method, you can try it with an IIFE for now: <code>(||{ ... function body here ... })();</code>)  In general I like the idea that anything you can produce from a <code>?</code> can be consumed by a <code>?</code>, and that the <code>Ok</code> type is the same in both cases.  The only asymmetric case that seems clearly interesting to me is being able to use <code>?</code> on a <code>Result&lt;T, !&gt;</code> in any method, but I don't know any <code>Try</code> designs that could do that without specialization.</p>
<p>From a different perspective, I think it's also nicer for the "you used <code>?</code> in a <code>-&gt; ()</code> function" to be able to say "you can't do that with this return type", than to have to give an error like "you can only do that on <code>Option</code> in here" -- I think more often when that's done by mistake people want to change the function to return a <code>Result</code> than to just do <code>.ok()?</code> and ignore the error.</p>
<p>(Thanks for the ping! Very timely; I've actually just been <a href="https://github.com/scottmcm/rust/pull/2">working on a new <code>Try</code> proposal</a>.  I should go rename one of those traits to <code>Bubble</code> <span aria-label="upside down" class="emoji emoji-1f643" role="img" title="upside down">:upside_down:</span>)</p>



<a name="220147660"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Implementing%20Try%20for%20unit/near/220147660" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Joshua Barretto <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Implementing.20Try.20for.20unit.html#220147660">(Dec 16 2020 at 17:41)</a>:</h4>
<blockquote>
<p>today that cannot be done without also allowing ()?????????? to be legal, which is undesirable</p>
</blockquote>
<p>I think that sounds more like a bug in the current design of <code>Try</code> to be honest, but I assume that's one of the motives for your new proposal.</p>



<a name="220148568"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Implementing%20Try%20for%20unit/near/220148568" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> scottmcm <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Implementing.20Try.20for.20unit.html#220148568">(Dec 16 2020 at 17:48)</a>:</h4>
<p>I don't know that it's necessarily a bug in the design.  From a feature coherence perspective, I think it's reasonable to have the property that if <code>x?</code> is legal, then you can also use <code>try { x? }</code> to get back to <code>x</code>.</p>
<p>But it's also true that <code>x + y</code> being legal tells you nothing about <code>x - y</code>, so one could also argue that there's no reason to couple things.</p>



<a name="220251927"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Implementing%20Try%20for%20unit/near/220251927" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Joshua Barretto <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Implementing.20Try.20for.20unit.html#220251927">(Dec 17 2020 at 14:49)</a>:</h4>
<p>I think the problem here is that, from my perspective, the <code>Try</code> trait defines the relationship between a type and the "result-like" that it decays into backwards. Currently you implement <code>Try</code> for the final result-like type, but switching this around (i.e: implementing it for the type that will decay to the result-like type) allows you to prevent the edge case that cuviper mentions.</p>



<a name="220254279"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Implementing%20Try%20for%20unit/near/220254279" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Joshua Barretto <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Implementing.20Try.20for.20unit.html#220254279">(Dec 17 2020 at 15:08)</a>:</h4>
<p>Here's an example of something I was imagining. It uses two traits, <code>Decay</code> and <code>Outcome</code>. <code>Decay</code> allows a type to have the <code>?</code> operator used upon it, whereas <code>Outcome</code> allows a type to be used as a target for the <code>?</code> operator (i.e: the result of a function). There are examples at the bottom demonstrating usage (using a macro analogous to the old <code>try</code> macro).</p>
<p><a href="https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2018&amp;gist=65d6c777ac25ec7341e48e4f34f0ec87">https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2018&amp;gist=65d6c777ac25ec7341e48e4f34f0ec87</a></p>
<p>This setup allows <code>Option</code> to be propagated into a <code>Result&lt;T, ()&gt;</code>, or a <code>()</code>, along with everything that the <code>Try</code> trait allows right now.</p>
<p>Of course, it's only a quick example so it doesn't include all of the useful extra stuff that <code>Try</code> has right now.</p>
<p>Together, the traits allow the propagation of arbitrary result-like types in much the same way as <code>Try</code> does now, but also allow types to opt into being propagated on a more precise basis to avoid edge cases like the one cuviper mentions.</p>



<a name="220296088"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Implementing%20Try%20for%20unit/near/220296088" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> scottmcm <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Implementing.20Try.20for.20unit.html#220296088">(Dec 17 2020 at 20:16)</a>:</h4>
<p>One <em>can</em> certainly separate the introduction and elimination (in the Gentzen sense) of the Result-like type into two different traits.  The question is entirely around whether libs (and maybe lang) wish to allow those interconversions -- it's my current understanding that allowing <code>?</code>-on-<code>Option</code> in a <code>-&gt; Result&lt;_, _&gt;</code> context is <em>not</em> something wanted, rather that it's desired that one uses <code>.ok_or(...)</code> in those situations.</p>



<a name="220302783"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Implementing%20Try%20for%20unit/near/220302783" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Joshua Barretto <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Implementing.20Try.20for.20unit.html#220302783">(Dec 17 2020 at 21:08)</a>:</h4>
<p>That specifically only works when the result is <code>Result&lt;_, ()&gt;</code> - at which point there's no functional difference between it and an <code>Option&lt;_&gt;</code> anyway (indeed, clippy will tell you to replace it). If anything, this feels like the correct behaviour.</p>



<a name="220321363"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Implementing%20Try%20for%20unit/near/220321363" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> scottmcm <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Implementing.20Try.20for.20unit.html#220321363">(Dec 18 2020 at 00:10)</a>:</h4>
<p>Depends whether <code>Result&lt;_, ()&gt;</code> is itself the correct thing to use.  <code>()</code> is not <code>std::error::Error</code>, so it's not obvious that's worth encouraging.  (The current unstable one can convert between <code>Option&lt;T&gt;</code> and <code>Result&lt;T, NoneError&gt;</code>, but even that isn't necessarily wanted and <code>NoneError</code> is not stable to be able to use that.)</p>



<a name="220398977"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Implementing%20Try%20for%20unit/near/220398977" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> cuviper <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Implementing.20Try.20for.20unit.html#220398977">(Dec 18 2020 at 17:02)</a>:</h4>
<p>I'm pretty sure I did show a stable way to use <code>NoneError</code> indirectly before, but I don't remember what I did offhand.</p>



<a name="220413629"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Implementing%20Try%20for%20unit/near/220413629" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> scottmcm <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Implementing.20Try.20for.20unit.html#220413629">(Dec 18 2020 at 18:54)</a>:</h4>
<p>As far as I know it can only be used indirectly for the option-&gt;result direction, like this: &lt;<a href="https://github.com/scottmcm/rust/blob/do-or-do-not/src/test/ui/try-on-option-in-result-method.rs#L5">https://github.com/scottmcm/rust/blob/do-or-do-not/src/test/ui/try-on-option-in-result-method.rs#L5</a>&gt;</p>



<a name="220422339"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Implementing%20Try%20for%20unit/near/220422339" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> cuviper <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Implementing.20Try.20for.20unit.html#220422339">(Dec 18 2020 at 20:08)</a>:</h4>
<p>yeah, that looks right</p>



<a name="220488510"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Implementing%20Try%20for%20unit/near/220488510" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Joshua Barretto <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Implementing.20Try.20for.20unit.html#220488510">(Dec 19 2020 at 21:38)</a>:</h4>
<blockquote>
<p>Depends whether Result&lt;_, ()&gt; is itself the correct thing to use. () is not std::error::Error, so it's not obvious that's worth encouraging</p>
</blockquote>
<p>I don't think such a proposal would encourage that. No more than the existing error handling setup does, anyway.</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>